
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections;
using System.Text;
using System.Xml;

using Swaf;
using Swaf.Config;
using Swaf.Container;

namespace Swaf.BizObj
{
	[Serializable]
	public class BizObjDef
	{
		public string type;
		public string extendsType;
		public string key;
		public string encrypt;
		public string expiration = null;
		public bool allFieldsProcessed = false;
		public IList OrderedFields = new ArrayList();

		public BizObjDef(string Type, string Extends, string Key, string Encrypt)
		{
			type = Type;
			extendsType = Extends;
			key = Key;
			encrypt = Encrypt;
		}
		public BizObjDef(XmlElement configInfo)
		{
			type = configInfo.GetAttribute("type");
			key = configInfo.GetAttribute("key");
			encrypt = configInfo.GetAttribute("encrypt");
            expiration = configInfo.GetAttribute("expire");
            if (encrypt.Equals(string.Empty))
				encrypt = "false";
			extendsType = configInfo.GetAttribute("extends");
			// dependent code requires extendsType being null if no extension specified.
			extendsType = (extendsType == string.Empty) ? null : extendsType;
			foreach (XmlNode node in configInfo.ChildNodes)
			{
				if (node is XmlElement)
				{
					switch (node.Name)
					{
						case "Field":
							FieldDefInfo fld = new FieldDefInfo(type, (XmlElement)node);
							addChildElement(fld);
							break;
						case "Method":
							MethodDef method = new MethodDef(type, (XmlElement)node);
							addChildElement(method);
							break;
					}
				}
			}
		}

		public void addChildElement(IFieldDef child)
		{
			OrderedFields.Add(child);
		}

		public IFieldDef getChildElement(string name)
		{
			foreach (IFieldDef child in OrderedFields)
				if (child.name == name)
					return child;
			return null;
		}

		/// <summary>
		/// Will put this instance into the global BizObjManager class using the internal methods
		/// available for inserting.
		/// </summary>
		public void insert()
		{
            create(true);
		}
        
        /// <summary>
        /// Will use the global BizObjManager to create an IBizObjDefinition
        /// </summary>
        /// <param name="bizObjMgrCache">Will insert it into the global BizObjManager if specified as true</param>
        /// <returns></returns>
        public IBizObjDefinition create(bool bizObjMgrCache)
        {
            BizObjManager mgr = Application.globalApp.bizObjMgr as BizObjManager;
            IBizObjDefinition boDef = null;
            
            // Define the bizobj type
            if (bizObjMgrCache)
            {
                mgr.defineBizObjType(type, key, extendsType, null, null, null, expiration);
                boDef = mgr.getBizObjDefinition(type);
            }
            else
            {
                mgr.defineBizObjType(type, key, extendsType, null, null, null, expiration, out boDef);
                
                // Set the expiration if it was specified.
                if (expiration != null && expiration != string.Empty)
                {
                    ICatalogItem ci = boDef as ICatalogItem;
                    ci.expiration = expiration;
                }
            }
            
            foreach (IFieldDef field in OrderedFields)
            {
                // define the fields
                if (field is FieldDefInfo)
                {
                    FieldDefInfo finfo = field as FieldDefInfo;
                    mgr.defineField(boDef, finfo.name, finfo.type, finfo.validators, finfo.aggregate, finfo.defaultValue, null, null);
                    foreach (DecoratorDef deco in finfo.decorators)
                        mgr.defineFieldDecorator(boDef, finfo.name, deco.decoratorName, deco.decoratorValue);
                }
                else if (field is MethodDef)
                {
                    // define the methods
                    MethodDef minfo = field as MethodDef;
                    mgr.defineMethod(boDef, minfo.name, minfo.language, minfo.scriptCode, minfo.parameters, null);
                }
            }

            return boDef;
        }
	}

	[Serializable]
	public class FieldDefInfo : IFieldDef
	{
		private string m_bizObjType;
		private string m_name;
		public string type;
		public string validators;
		public string aggregate;
		public string defaultValue;
		public IList m_decorators = new ArrayList();
		private bool m_processed = false;
		public FieldDefInfo(string BizObjType, string Name, string Type, string Validators, string Aggregate, string DefaultValue)
		{
			m_bizObjType = BizObjType;
			m_name = Name;
			type = Type;
			validators = Validators;
			aggregate = Aggregate;
			defaultValue = DefaultValue;
		}
		public FieldDefInfo(string BizObjType, XmlElement configInfo)
		{
			m_bizObjType = BizObjType;
			m_name = configInfo.GetAttribute("name");
			type = configInfo.GetAttribute("type");
			defaultValue = null;
			if (configInfo.GetElementsByTagName("NULL").Count == 0)
			{
				defaultValue = configInfo.InnerText;
				if (defaultValue == null)
					defaultValue = "";
			}
			validators = configInfo.GetAttribute("validator");
			aggregate = configInfo.GetAttribute("aggregate");
			if (aggregate.Equals(string.Empty))
				aggregate = "true";

			foreach (XmlAttribute att in configInfo.Attributes)
			{
				if (!(att.Name.Equals("name") || att.Name.Equals("type") || att.Name.Equals("validator") || att.Name.Equals("aggregate")))
				{
					m_decorators.Add(new DecoratorDef(att.Name, att.InnerText));
				}
			}

		}
		public bool processed
		{
			get { return m_processed; }
			set { m_processed = value; }
		}
		public string bizObjType
		{
			get { return m_bizObjType; }
		}
		public string name
		{
			get { return m_name; }
		}
		public IList decorators
		{
			get { return m_decorators; }
		}
		public void addDecorator(string name, string value)
		{
			decorators.Add(new DecoratorDef(name, value));
		}
	}

	[Serializable]
	public class MethodDef : IFieldDef
	{
		private string m_bizObjType;
		private string m_name;
		public string language;
		public string scriptCode;
		public string parameters;
		private IList m_decorators = new ArrayList();
		private bool m_processed = false;
		public MethodDef(string BizObjType, string Name, string lang, string code, string parms)
		{
			m_bizObjType = BizObjType;
			m_name = Name;
			language = lang;
			scriptCode = code;
			parameters = parms;
		}
		public MethodDef(string BizObjType, XmlElement configInfo)
		{
			m_bizObjType = BizObjType;
			m_name = configInfo.GetAttribute("name");
			parameters = configInfo.GetAttribute("parameters", "");
			language = configInfo.GetAttribute("language", "jscript");
			scriptCode = configInfo.InnerText;
			if (scriptCode.StartsWith("<![CDATA["))
				scriptCode = scriptCode.Substring(9, scriptCode.Length - 12);
			foreach (XmlAttribute att in configInfo.Attributes)
			{
				if (!(att.Name.Equals("name") || att.Name.Equals("parameters") || att.Name.Equals("language")))
				{
					m_decorators.Add(new DecoratorDef(att.Name, att.InnerText));
				}
			}

		}
		public bool processed
		{
			get { return m_processed; }
			set { m_processed = value; }
		}
		public void addDecorator(string name, string value)
		{
			decorators.Add(new DecoratorDef(name, value));
		}
		public string bizObjType
		{
			get { return m_bizObjType; }
		}
		public string name
		{
			get { return m_name; }
		}
		public IList decorators
		{
			get { return m_decorators; }
		}

	}

	[Serializable]
	public class DecoratorDef
	{
		public string decoratorName;
		public string decoratorValue;
		public DecoratorDef(string Name, string Value)
		{
			decoratorName = Name;
			decoratorValue = Value;
		}
	}
}
